import { extend } from 'umi-request';
import { useTabsStore, useUserStore } from '@/store/index.js';
import ModalUtil from '@/utils/modal.js';
import {
  ERROR,
  NO_LOGIN,
  NO_PERMISSION,
  NOT_FOUND,
  SERVICE_ERROR,
  SUCCESS,
  WARN
} from '@/constants/statusConstant.js';
import { v4 as uuid } from 'uuid';

/**
 * 创建一个全局的 AbortController 对象, 用于取消请求
 */
let abortControllers = {};

/**
 * 取消当前的请求
 */
export const cancelRequest = (requestId) => {
  if (abortControllers[requestId]) {
    abortControllers[requestId].abort();
    delete abortControllers[requestId];
  }
};

/**
 * 获取请求ID
 */
export const getRequestId = () => {
  return `api-${uuid()}`;
};

// 状态码
const codeMaps = {
  200: '服务器成功返回请求的数据',
  201: '新建或修改数据成功',
  202: '一个请求已经进入后台排队（异步任务）',
  204: '删除数据成功',
  400: '请求有误',
  401: '用户名或密码错误',
  403: '用户得到授权，但是访问是被禁止的',
  404: '请求失败，结果不存在',
  405: '操作失败',
  406: '请求的格式不可得',
  410: '请求的资源被永久删除',
  422: '操作失败',
  500: '服务器发生错误，请检查服务器',
  502: '网关错误',
  503: '服务不可用，服务器暂时过载或维护',
  504: '网关超时'
};

/**
 * 异常处理程序
 */
const errorHandler = (error) => {
  const { response } = error;
  if (!response) {
    if (error.type === 'AbortError') {
      return;
    }
    if (error.type === 'Timeout') {
      ModalUtil.error('请求超时，请诊断网络后重试');
      return;
    }
    ModalUtil.error('无法连接服务器');
  } else if (response && response.status) {
    const errorText = codeMaps[response.status] || response.statusText;
    ModalUtil.error(errorText);
  }
  return response;
};

export const RequestUtil = extend({
  charset: 'utf8',
  prefix: '/api',
  timeout: 10 * 1000,
  timeoutMessage: '请求超时，请诊断网络后重试',
  errorHandler: errorHandler
});

RequestUtil.interceptors.request.use((url, options) => {
  let newOptions = { ...options };

  if (options?.requestId) {
    let abortController = new AbortController();
    // 存储当前请求的 AbortController 对象
    abortControllers[options.requestId] = abortController;
    newOptions.signal = abortController.signal;
  }

  // 添加Token
  const token = useUserStore.getState().token;
  if (token) {
    newOptions.headers['Authorization'] = `Bearer ${token}`;
  }

  // 设置Content-Type
  newOptions.headers['Content-Type'] = 'application/json';

  // 处理FormData
  if (options.body instanceof FormData) {
    delete newOptions.headers['Content-Type'];
  }

  // 处理Content-Type
  if (options.content_type) {
    newOptions.headers['Content-Type'] = options.content_type;
    delete newOptions['content_type'];
  }

  return {
    url: url,
    options: newOptions
  };
});

RequestUtil.interceptors.response.use(async (response, options) => {
  // 删除请求ID对应的 AbortController 对象
  if (options?.requestId) {
    delete abortControllers[options.requestId];
  }
  const data = await response.json();
  const code = data.code;
  const msg = data.msg;
  if (data && code !== SUCCESS) {
    switch (code) {
      case WARN:
        ModalUtil.warn(msg);
        break;
      case NO_LOGIN:
        ModalUtil.error(
          '未登录 或 登录已过期，请重新登录',
          () => {
            // 清除用户信息
            useUserStore.getState().clear();
            // 清除标签页
            useTabsStore.getState().clear();
            // 跳转到登录页面
            if (window.location.pathname !== '/login') {
              window.location.href = '/login';
            }
          },
          'loginError'
        );
        return Promise.reject('无效的会话，或者会话已过期，请重新登录。');
      case NO_PERMISSION:
        ModalUtil.warn(msg);
        break;
      case NOT_FOUND:
        ModalUtil.error(msg);
        break;
      case SERVICE_ERROR:
        ModalUtil.error(msg);
        break;
      case ERROR:
        ModalUtil.error(msg);
        break;
      default:
        ModalUtil.error('系统未知错误，请反馈给管理员');
        return Promise.reject('error');
    }
  }
  return data;
});
